package tracingservice

import (
	"alarmservice/model"
	"alarmservice/service"
	"errors"
	"time"

	"github.com/astaxie/beego"
	"github.com/kaixinmao/cronexpr"
)

//tracing处理相关类，具体数据处理还请使用model相关方法
type Tracing struct {
	Id    int64
	Model *model.Tracing
}

//接口 满足 外部对Tracing的调用需求
type ITracing interface {
	GetModel() *model.Tracing
	Trigger(data string) error
	DoDisabled() error
	DoEnabled() error
	DoDeleted() error
}

//根据model生成ITracing
func NewITracing(modelTracing *model.Tracing) (ITracing, error) {
	var i ITracing
	if modelTracing == nil {
		return nil, errors.New("empty model tracing")
	}

	if modelTracing.Type == model.TracingTypeTrigger {
		triggert, err := NewTriggerTracing(modelTracing)
		i = triggert
		return i, err
	}

	if modelTracing.Type == model.TracingTypeTimer {
		timert, err := NewTimerTracing(modelTracing)
		i = timert
		return i, err
	}

	return nil, errors.New("unknow type")
}

//通过监控类型做特殊检查，错误信息将直接返回给用户展示
func CheckPostTracingDataByType(modelTracing *model.Tracing) (bool, error) {
	if modelTracing.Type != model.TracingTypeTimer {
		return true, nil
	}

	if modelTracing.TracingTime == "" {
		return false, errors.New("定时监控规则为空")
	}

	_, err := cronexpr.Parse(modelTracing.TracingTime)
	if err != nil {
		return false, errors.New("定时监控规则解析错误")
	}

	return true, nil
}

func (t *Tracing) saveNewWarning(data string) error {
	modelTracing := t.Model
	w := model.NewWarning(modelTracing.ProjectId, modelTracing.Id, data)

	err := model.Insert(w)
	if err != nil {
		return err
	}

	return nil
}

func (t *Tracing) SendWarningMsg() error {
	modelProject := &model.Project{}
	err := model.GetById(t.Model.ProjectId, modelProject)

	if err != nil {
		return err
	}

	followProjects := make(model.SliceFollowProject, 0)

	err = model.Orm.Where("project_id=?", modelProject.Id).Find(&followProjects)

	if err != nil {
		return err
	}

	mobileLogins, err := model.GetMobileLoginFromUserIdContainer(followProjects)
	if err != nil {
		return err
	}

	if len(mobileLogins) == 0 {
		return nil
	}

	androidUids := make([]int64, 0)
	iosUids := make([]int64, 0)

	//解析不同系统，准备发送消息
	for _, v := range mobileLogins {
		switch v.Os {
		case "android":
			androidUids = append(androidUids, v.Uid)
		case "ios":
			iosUids = append(iosUids, v.Uid)
		}
	}

	msgContent := modelProject.Title + ":\"" + t.Model.Key + "\"发生报警!"

	if len(androidUids) > 0 {
		//发送android信息
		msg, err := service.FastGetAndroidMessage("IOT报警", msgContent)
		if err != nil {
			beego.Error(err)
			return err
		}
		err = service.PushAndroidMessageByUids(msg, androidUids)
		if err != nil {
			beego.Error(err)
			return err
		}
	}

	if len(iosUids) > 0 {
		msg, err := service.FastGetIosMessage(msgContent)
		if err != nil {
			beego.Error(err)
			return err
		}
		err = service.PushIOSMessageByUids(msg, iosUids, beego.AppConfig.String("runmode"))

		if err != nil {
			beego.Error(err)
			return err
		}
	}

	return nil
}

func (t *Tracing) Trigger(data string) error {
	return nil
}

func (t *Tracing) GetModel() *model.Tracing {
	return t.Model
}

func (t *Tracing) DoDeleted() error {
	return nil
}

func (t *Tracing) DoEnabled() error {
	return nil
}

func (t *Tracing) DoDisabled() error {
	return nil
}

func Init() {
	//初始化值
	TTSchedule = TimerTracingSchedule{}
	TTSchedule.LastTriggerTimes = make(map[int64]time.Time)
	TTSchedule.TimeTracingIdsMap = make(map[string][]int64)
	TTSchedule.LoadTimerTracings()
	TTSchedule.run()
}
